package com.sig;

import java.io.File;
import java.security.acl.LastOwnerException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.StringTokenizer;

import myinterface.INoeud;

import org.codehaus.jackson.map.ObjectMapper;

import utils.Graphe;
import utils.Polygon;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SlidingDrawer;
import android.widget.TextView;
import android.widget.Toast;
import arbre.utils.ArbreBinaire;
import arbre.utils.ContentNode;
import arbre.utils.Noeud;
import arbre.utils.Point;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.navdrawer.SimpleSideDrawer;
import com.sig.formes.Forme;
import com.sig.formes.IForme;
import com.sig.formes.Layer;
import com.sig.formes.Localisator;
import com.sig.formes.Polyedre;
import com.sig.formes.Segment;
import com.sig.net.NetGraphe;
import com.sig.net.core.Net;
import com.sig.opengl.MyGLRenderer;
import com.sig.opengl.MyGLSurfaceView;
import com.sig.xml.MapXmlParser;


@SuppressWarnings("deprecation")
public class MainActivity extends FragmentActivity implements View.OnClickListener,LocationListener{
	public static boolean modeBatiment = false;
	public static boolean modeOnline = false;

	public static String SESSION_VERSION = "VERSION";
	public static String SESSION_KEY_VERSION = "VERSION_KEY";


	public static MyGLSurfaceView _surfaceView;
	public static float position_x_batiment ;
	public static float position_y_batiment ;
	private Graphe graphe;
	private Graphe batiment;
	private SimpleSideDrawer _slider;
	View _openSlider;
	SlidingDrawer _slidingDrawer;
	View _recherche_layout;
	EditText _recherche;
	View _recherche_itineraire;

	ImageButton _btngeoloc;
	String _status_button_geoloc;
	View _search_btn;
	View _search_user;
	ImageButton _button_compass;
	boolean button_itineraire = false;
	ViewGroup _sliderLayout;
	View _onlineMode;

	Recherche recherche = null;
	Itineraire itineraire = null;
	utils.Point myposition = new utils.Point(0, 1);


	ListView _slider_list_enabler_layer;
	ListView _slider_list_enable_layer_batiment;
	private LocationManager locationManager;

	//localisation GPS
	private Location location;
	public Localisator ImHere;
	private double latitude;
	private double longitude;
	private boolean location_enabled =false;
	private ArbreBinaire arbrePolyedres;
	private ArbreBinaire arbreChemins;

	public static  String id_source;
	public static String type_point_source;

	public static INoeud source_batiment;
	public static INoeud source_map ;
	public static INoeud puits;
	public static Context ctx;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);


		ctx = getApplicationContext();

		_surfaceView = (MyGLSurfaceView)findViewById(R.id.opengl_view);

		_slider = new SimpleSideDrawer( this );
		_slider.setLeftBehindContentView( R.layout.slider);

		_btngeoloc = (ImageButton) findViewById(R.id.button_geolocalisation);
		_btngeoloc.setImageResource(R.drawable.ic_location);
		_btngeoloc.setOnClickListener(this);
		_status_button_geoloc="DEFAULT";

		_search_btn = findViewById(R.id.search_search);
		_search_btn.setOnClickListener(this);

		_search_user = findViewById(R.id.search_user);
		_search_user.setOnClickListener(this);

		_button_compass = (ImageButton)findViewById(R.id.button_compass);
		_button_compass.setOnClickListener(this);

		_openSlider = findViewById(R.id.open_slider);
		_openSlider.setOnClickListener(this);

		_slidingDrawer = (SlidingDrawer)findViewById(R.id.slidingDrawer);
		_sliderLayout = (ViewGroup)findViewById(R.id.sliding_drawer_layout);

		_slider_list_enabler_layer = (ListView) _slider.getLeftBehindView().findViewById(R.id.slider_list_enable_layer);
		_slider_list_enable_layer_batiment = (ListView) _slider.getLeftBehindView().findViewById(R.id.slider_list_enable_layer_batiment);
		_recherche_layout = findViewById(R.id.search);

		_recherche_itineraire = findViewById(R.id.search_itineraire);
		_recherche_itineraire.setOnClickListener(this);

		_recherche = (EditText)findViewById(R.id.search_edit);

		_onlineMode = findViewById(R.id.slider_mode_online);
		_onlineMode.setOnClickListener(this);

		//location variables
		this.ImHere = new Localisator();

		//binary Trees
		arbrePolyedres=new ArbreBinaire();
		arbreChemins=new ArbreBinaire();

		charger();

		_recherche.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(final View v, boolean focus) {
				if(focus){
					_recherche.setText("");
					ouvrirRecherche(false);
					recherche.liste.setOnItemClickListener(new OnItemClickListener() {
						@Override
						public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {

							puits = recherche.retourner(position);
							_recherche.setText(((Polygon)puits).getNom());
							fermerRecherche();

							//TODO: kevin ici !
							//itineraire.changerDestination(p.getNom());

							InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
							imm.hideSoftInputFromWindow(_recherche.getWindowToken(), 0);

							if(modeOnline){
								if(!modeBatiment)
									new DemanderCheminTask().execute(source_map.getId(),puits.getId());
								else
									new DemanderCheminTask().execute(source_batiment.getId(),puits.getId());
							}
							else{
								if(!modeBatiment){
									ajouterChemin(source_map,null,puits,null);
								}else{
									ajouterChemin(source_batiment,null,puits,null);
								}
							}
						}
					});
				}else{
					if(!button_itineraire){
						fermerRecherche();
					}
					InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
					imm.hideSoftInputFromWindow(_recherche.getWindowToken(), 0);
				}
			}
		});

		//enableLocationTracker();
		//afficherSegment();
	}

	private void enableLocationTracker() {
		/*
		 * 
		 * on va test le gps
		 * 
		 */
		// Acquire a reference to the system Location Manager
		if(locationManager == null){
			locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		}
		if(locationManager != null){
			startUsingGPS();
		}

	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		stopUsingGPS();
	}



	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		stopUsingGPS();
		super.onPause();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		enableLocationTracker();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		stopUsingGPS();
		super.onStop();
	}

	private void HandleLocationChanged(Location location) {
		if(location != null){
			this.location = location;
			Toast.makeText(this, "lat : "+ location.getLatitude()+" lon : "+location.getLongitude() , Toast.LENGTH_SHORT).show();

		}

	}
	public void ouvrirRecherche(boolean itineraire){
		_search_user.setOnClickListener(null);

		if(!_slidingDrawer.isOpened()){
			_slidingDrawer.open();
		}
		if(itineraire){
			_sliderLayout.removeAllViews();
			_recherche_layout.setVisibility(View.GONE);

			if(modeBatiment){
				this.itineraire = new Itineraire(this,_sliderLayout,graphe);
			}else{
				this.itineraire = new Itineraire(this,_sliderLayout,batiment);

			}

		}else{
			//TODO changé
			if(!modeBatiment){
				recherche = new Recherche(this,_sliderLayout,graphe.getPolygones());
			}else{
				Log.e("MainActivity","Batiment");
				recherche = new Recherche(this,_sliderLayout,batiment.getPolygones());

			}

		}


		_recherche.addTextChangedListener(new TextWatcher() {
			@Override
			public void afterTextChanged(Editable s) {}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
				if(recherche != null)
					recherche.chercher(s.toString());
				else
					_recherche.removeTextChangedListener(this);
			}                       
		});
	}

	public void fermerRecherche(){
		if(_slidingDrawer.isOpened()){
			_slidingDrawer.close();
			_sliderLayout.removeAllViews();
			_recherche.clearFocus();
			recherche = null;
			_recherche_layout.setVisibility(View.VISIBLE);
			_search_user.setOnClickListener(this);
		}
	}

	@Override
	public void onBackPressed() {
		if(_slidingDrawer.isOpened()){
			fermerRecherche();
		}
		else
			super.onBackPressed();
	}

	public void onClick(View v){
		switch(v.getId()){
		case R.id.open_slider:
			_slider.toggleLeftDrawer();
			break;
			/*case R.id.button_chercher_chemin :
                        Log.e("MainActivity","onclick");
                        break;*/
		case R.id.search_itineraire:
			button_itineraire = true;
			ouvrirRecherche(true);
			break;
		case R.id.button_geolocalisation:
			if(!modeBatiment){
				commuteButtonGeolocalisation();
			}else{
				getQrCode();
			}
			break;
		case R.id.search_user:
			modeBatiment();
			break;
		case R.id.slider_mode_online:
			switchModeOnline();
		}
	}

	private void switchModeOnline(){
		modeOnline = !modeOnline;
		if(modeOnline){
			((TextView)_onlineMode.findViewById(R.id.text)).setTextColor(Color.WHITE);

		}else{
			((TextView)_onlineMode.findViewById(R.id.text)).setTextColor(Color.GRAY);
		}
		demanderIP();
	}

	public void getQrCode(){
		//instantiate ZXing integration class
		IntentIntegrator scanIntegrator = new IntentIntegrator(this);
		//start scanning
		scanIntegrator.initiateScan();
	}

	private void modeBatiment() {

		for(Entry<String, Layer> l : _surfaceView.getRenderer().get_layers().entrySet()){
			l.getValue().getParam().setEnable(modeBatiment);
		}

		if(!modeBatiment){

			Log.e("MODE BATIMENT","TRUE");
			// On change la caméra
			_surfaceView.changerCamera(1480f, 47249f, 2500f);

			// On met le slider pour le batiment
			_slider_list_enabler_layer.setVisibility(View.GONE);
			_slider_list_enable_layer_batiment.setVisibility(View.VISIBLE);

			// On rend que les couches du batiment visible
			_surfaceView.getRenderer().get_layers().get("dijkstraa").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("salle").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("couloir").getParam().setEnable(true);      
			_surfaceView.getRenderer().get_layers().get("mur").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("toilette").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("porte").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("lettre").getParam().setEnable(true);
			_surfaceView.getRenderer().get_layers().get("sol").getParam().setEnable(true);

		}else{
			Log.e("MODE BATIMENT","FALSE");

			_surfaceView.changerCamera(MyGLRenderer.ancien_x, MyGLRenderer.ancien_y, MyGLRenderer.ancien_z);
			_surfaceView.getRenderer().get_layers().get("salle").getParam().setEnable(false);
			_surfaceView.getRenderer().get_layers().get("couloir").getParam().setEnable(false);     
			_surfaceView.getRenderer().get_layers().get("mur").getParam().setEnable(false);
			_surfaceView.getRenderer().get_layers().get("toilette").getParam().setEnable(false);
			_surfaceView.getRenderer().get_layers().get("porte").getParam().setEnable(false);
			_surfaceView.getRenderer().get_layers().get("lettre").getParam().setEnable(false);
			_surfaceView.getRenderer().get_layers().get("sol").getParam().setEnable(false);

			_slider_list_enabler_layer.setVisibility(View.VISIBLE);
			_slider_list_enable_layer_batiment.setVisibility(View.GONE);
		}

		modeBatiment = !modeBatiment;
		_surfaceView.requestRender();

	}

	private void commuteButtonGeolocalisation() {
		if(_status_button_geoloc.equalsIgnoreCase("default")){
			_status_button_geoloc="GPS_ENABLED";
			_btngeoloc.setImageResource(R.drawable.ic_location_active);
			enableLocationTracker();
			this.location_enabled= true;
			Log.v("location","gps enabled");
		}
		else if(_status_button_geoloc.equalsIgnoreCase("GPS_ENABLED")){
			_status_button_geoloc="BOUSSOLE";
			_btngeoloc.setImageResource(R.drawable.ic_compass_mode);
			enableLocationTracker();
			this.location_enabled= true;
			Log.v("location","gps enabled");
		}
		else if(_status_button_geoloc.equalsIgnoreCase("BOUSSOLE")){
			_status_button_geoloc="DEFAULT";
			_btngeoloc.setImageResource(R.drawable.ic_location);
			disableLocationTracker();
			this.location_enabled= false;
			Log.v("location","gps disabled");
		}
		//              _btngeoloc.setSelected(!_btngeoloc.isSelected());

		//_surfaceView.getRenderer().ajouterFormes(getFormes());
	}



	private void disableLocationTracker() {
		this.location_enabled = false;
		this.locationManager.removeUpdates(this);

		if(_surfaceView != null &&_surfaceView.getRenderer()!=null)
		{
			Layer loc = _surfaceView.getRenderer().get_layers().get("localisation");
			if(loc != null)
			{
				loc.getParam().setEnable(this.location_enabled);
				Log.v("location","disableLocationTracker : location Layer is disabled");
			}
			_surfaceView.requestRender();
		}
	}

	private void charger(){
		String xml = LecteurFichier.readFileFromSDCard("map.xml");
		String xmlBatiment = LecteurFichier.readFileFromSDCard("batiment.xml");

		MapXmlParser parseur = new  MapXmlParser(xml);
		graphe = parseur.getMap();
		MapXmlParser.parseBatiment = true;
		parseur = new  MapXmlParser(xmlBatiment);
		batiment = parseur.getMap();
		chargerArbres();
		chargerDonnees();
		//Log.e("testLoca", localiser(new utils.Point(1932.7955f, 47845.363f)).toString());
	}
	private static final String POLYGON_TREE_PATH="arbrePolygon.json";
	private static final String CHEMIN_TREE_PATH="arbreChemin.json";

	private void chargerArbres(){
		Log.e("MainActivity - chargerArbre", "on commence la charge");
		ObjectMapper mapper = new ObjectMapper();
		try{
			File directory = Environment.getExternalStorageDirectory();
			File filePolygon = new File(directory + "/sig/"+POLYGON_TREE_PATH);
			ArbreBinaire ar = mapper.readValue(filePolygon, ArbreBinaire.class);
			Log.e("MainActivity - chargerArbre", "ca lit polygon");
			arbrePolyedres.setRacine(ar.getRacine());

			//			File fileChemin = new File(directory + "/sig/"+CHEMIN_TREE_PATH);
			//			ArbreBinaire ar2 = mapper.readValue(fileChemin, ArbreBinaire.class);
			//			Log.e("MainActivity - chargerArbre", "ca lit chemin");
			//			arbreChemins.setRacine(ar2.getRacine());
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	public ContentNode localiser(utils.Point p){
		ContentNode res = null;
		//		res = localiserChemin(arbreChemins.getRacine(),p);
		//		if(res == null || res.getId().equalsIgnoreCase("DEFAULT")){
		//			Log.e("localiser", "pas de chemin, on passe aux polygons");
		res = localiserPolygon(arbrePolyedres.getRacine(),p);
		res.setT("poly");
		return res;
		//		}else{
		//			res.setT("chemin");
		//			return res;	
		//		}
	}

	private ContentNode localiserPolygon(Noeud n,utils.Point p) {
		//verticale
		if(n.getC().getT().equals("v")){
			if(p.getX() <= n.getC().getA()){
				return localiserPolygon(n.getL(), p);
			}
			else{
				return localiserPolygon(n.getR(), p);
			}
		}
		//segment
		else if(n.getC().getT().equals("s")){
			int rank = Integer.parseInt(n.getC().getId().substring(n.getC().getId().lastIndexOf("_")+1));
			String segID = n.getC().getId().substring(0, n.getC().getId().lastIndexOf("_"));
			Log.e("local poly rank", n.getC().getId()+", r: "+rank +" id : "+segID+" , "+graphe.getPolygones().get(segID));
			utils.Segment s= new utils.Segment(segID, graphe.getPolygones().get(segID).getPoly().get(rank), graphe.getPolygones().get(segID).getPoly().get(rank+1));
			if(s.dessous(p)){
				return localiserPolygon(n.getL(), p);
			}else if(s.dessus(p)){
				return localiserPolygon(n.getR(), p);
			}else{
				return new ContentNode("poly",segID,-100000f,null,null);
			}
		}
		else if(n.getC().getT().equals("z")){
			System.out.println("zone"  + n.getC().toString());
			return n.getC();
		}
		System.out.println(n.getC().toString());
		return n.getC();
	}

	private ContentNode localiserChemin(Noeud n,utils.Point p) {
		if(n.getC().getT().equals("v")){
			//verticale
			if(p.getX()<= n.getC().getA()){
				return localiserChemin(n.getL(), p);
			}
			else{
				return localiserChemin(n.getR(), p);
			}
		}
		else if(n.getC().getT().equals("s")){
			// l'id du segment est n.getC.getId()
			Log.d("segmetn ID", n.getC().getId());
			utils.Segment s = graphe.getChemins().get(n.getC().getId());
			if(s.dessous(p)){
				return localiserChemin(n.getL(), p);
			}
			if(s.dessus(p)){
				return localiserChemin(n.getR(), p);
			}
			//sur
			return n.getC();
		}
		else if(n.getC().getT().equals("z")){
			return n.getC();
		}
		return null;
	}

	private void chargerDonnees(){
		source_map = graphe.getPolygones().get("-1717203");
		source_batiment = batiment.getPolygones().get("17");

		try{
			Log.e("MainActivity","On demande les formes");

		}catch(Exception e){
			e.printStackTrace();
		}

		//_surfaceView.getRenderer().ajouterFormes(getFormes());

		//ajout des layers
		populateLayers(_surfaceView.getRenderer().get_layers(),graphe);

		populateLayers(_surfaceView.getRenderer().get_layers(),batiment);
		//ajout de la forme au layer localisation
		populate_localisation(_surfaceView.getRenderer().get_layers());

		//ajout des layer au slider_list_layer_enabler
		this._slider_list_enabler_layer.setAdapter(new LayerEnablerAdapter(this,_surfaceView.getRenderer().get_layers()));
		this._slider_list_enable_layer_batiment.setAdapter(new LayerEnablerAdapter(this,_surfaceView.getRenderer().get_layers_batiments()));

		_surfaceView.changerCamera(1934.7883f, 47845.01f, 30);
		_surfaceView.requestRender();


	}


	private void populate_localisation(HashMap<String, Layer> layers) {

		Layer l = layers.get("localisation");

		if(l != null)
			l.add_Forme(this.ImHere);               
		else           
			Log.e("localisation", "le layer localisation n'existe pas");


	}



	/**
	 * @param layers hashmap contenant les differents layers
	 * ajoute les polygones aux different layers
	 */
	private void populateLayers(HashMap<String, Layer> layers,Graphe g) {
		for(Entry<String, Polygon> entry : g.getPolygones().entrySet()) {
			Polygon polygon = entry.getValue();
			//recuperation de la cle du layer
			String key_layer;
			if(layers.keySet().contains(polygon.getType()))
			{
				key_layer = polygon.getType(); 
			}
			else 
			{
				key_layer = MyGLRenderer.DEFAULT_LAYER;
			}

			//Récupération du layer
			Layer l  = layers.get(key_layer);

			if(l != null)
			{
				// transformation du polygon en polyedre
				Polyedre poly = Polyedre.convert(polygon, l.getColor());
				// Log.e("MainActivity Poly info",poly.getPoints().get(0).getX()+"");
				//ajout
				l.add_Forme(poly);
			}
			else 
			{
				Log.e("sig_layer_error", "le layer "+key_layer+" n'existe pas");
			}
		}

		//ajout des routes
		for(Entry<String, utils.Segment> entry : g.getChemins().entrySet()) {
			utils.Segment c = entry.getValue();
			String key_layer= c.getType();
			Layer l;
			if(layers.containsKey(key_layer))
			{
				l = layers.get(key_layer);
			}
			else
			{
				l = layers.get(key_layer);
			}
			if(l != null){


				float epaisseur = 0.01f;
				float [] color = null;

				if(c.getType().equals("route"))
				{
					epaisseur= 0.02f;
					color = Forme.blanc;
				}
				if(c.getType().equals("chemin"))
				{
					epaisseur= 0.01f;
					color = Forme.jaune;
				}
				if(c.getType().equals("autre"))
				{
					epaisseur= 0.02f;
				}
				if(c.getType().equals("couloir"))
				{
					epaisseur= 1f;
					color = Forme.vert;
				}

				com.sig.formes.Segment sf =
						com.sig.formes.Segment.convert(entry.getValue(), color,epaisseur);
				l.add_Forme(sf);
			}
		}
	}

	public void ajouterChemin(INoeud source, utils.Point pointSource, INoeud puits, utils.Point pointPuit){
		if(_surfaceView  != null){
			_surfaceView.getRenderer().ajouterChemin(trouverChemin(source,pointSource,puits,pointPuit));                    
			_surfaceView.requestRender();
		}
	}

	public List<Forme> trouverChemin(INoeud source, utils.Point pointSource, INoeud puits, utils.Point pointPuit){

		List<INoeud> chemins;

		if(!modeBatiment){
			chemins = graphe.plusCourtChemin(source,puits);
		}else{
			Log.e("Batiment","true");
			chemins = batiment.plusCourtChemin(source, puits);
		}

		return afficherChemin(chemins);

	}

	/*
	public void afficherSegment(){
		String id = "477549410_6005";
		List<INoeud> noeuds = new ArrayList<INoeud>();
		noeuds.add(graphe.getChemins().get(id));
		_surfaceView.getRenderer().ajouterChemin(afficherChemin(noeuds));
	}

	 */
	public List<Forme> afficherChemin(List<INoeud> chemins){

		List<Forme> formes = new ArrayList<Forme>();

		for(INoeud inoeud : chemins){
			Log.e("INoeud",inoeud.toString());

			if(inoeud.getClass() == utils.Polygon.class){

				Polygon p = (Polygon) inoeud;
				formes.add(Polyedre.convert(p, Forme.rouge));

			}else{

				if(inoeud.getClass() == utils.Segment.class){
					utils.Segment s = (utils.Segment)inoeud;
					/*
                                        com.sig.formes.Point pD = new Point(s.getDebut().getX(), s.getDebut().getY());
                                        com.sig.formes.Point pF = new Point(s.getFin().getX(), s.getFin().getY());

                                        Segment segment = new Segment(pD, pF,3f);
                                        segment.color = Forme.bleuclair;
                                        segment.dessinerBord = false;

					 */
					Segment ss  = null;

					if(modeBatiment){
						ss = com.sig.formes.Segment.convert(s, Forme.bleuclair,1f);
					}else{
						ss = com.sig.formes.Segment.convert(s, Forme.bleuclair,0.01f);	
					}
					formes.add(ss);                         
				}
			}
		}

		return formes;
	}
	public List<IForme> getFormes(){
		List<IForme> formes = new ArrayList<IForme>();

		for(Entry<String,Polygon> entry : graphe.getPolygones().entrySet()) {
			Polygon polygon = entry.getValue();

			float[] couleurs = Forme.defaut;
			if(polygon.getType().equals("building"))
				couleurs = Forme.gris;
			if(polygon.getType().equals("brownfield"))
				couleurs = Forme.marron;
			if(polygon.getType().equals("construction"))
				couleurs = Forme.marron_clair;
			if(polygon.getType().equals("meadow"))
				couleurs = Forme.marron_clair;
			else if(polygon.getType().equals("university"))
				couleurs = Forme.rouge;
			else if(polygon.getType().equals("grass"))
				couleurs = Forme.vert;
			else if(polygon.getType().equals("commercial"))
				couleurs = Forme.jaune;
			else if(polygon.getType().equals("basin"))
				couleurs = Forme.bleuclair;
			else if(polygon.getType().equals("cemetery"))
				couleurs = Forme.noir;
			else if(polygon.getType().equals("forest"))
				couleurs = Forme.vert_fonce;
			else if(polygon.getType().equals("farmland"))
				couleurs = Forme.violet;
			else if(polygon.getType().equals("industrial"))
				couleurs = Forme.gris;
			else if(polygon.getType().equals("residential"))
				couleurs = Forme.rose;
			else if(polygon.getType().equals("trou")){
				couleurs = Forme.defaut;
			}

			Polyedre polyedre = Polyedre.convert(polygon, couleurs);
			formes.add(polyedre);
		}

		return formes;
	}

	public void showAlertQrCode(Polygon b){
		new AlertDialog.Builder(this)
	    .setTitle("Localisation dans le bâtiment")
	    .setMessage("Se localiser dans la salle : " + b.getNom())
	    .setPositiveButton("D'accord", new DialogInterface.OnClickListener() {
	        public void onClick(DialogInterface dialog, int which) { 
				source_batiment = batiment.getPolygones().get(id_source);
				List<INoeud> listes = new ArrayList<INoeud>();
				listes.add(batiment.getPolygones().get(id_source));
				_surfaceView.getRenderer().ajouterChemin(afficherChemin(listes));
				_surfaceView.requestRender();
	        }
	     })
	    .setNegativeButton("Refuser", new DialogInterface.OnClickListener() {
	        public void onClick(DialogInterface dialog, int which) { 
	            // do nothing
	        }
	     })
	     .show();
	}

	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		//retrieve result of scanning - instantiate ZXing object
		IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
		//check we have a valid result
		if (scanningResult != null) {
			//get content from Intent Result
			try{
				String scanContent = scanningResult.getContents();
				//get format name of data scanned

				StringTokenizer tk = new StringTokenizer(scanContent, ",");
				type_point_source = tk.nextToken();
				id_source = tk.nextToken().trim();

				if(type_point_source.equals("salle")){
					showAlertQrCode(batiment.getPolygones().get(id_source));

				}else{
					source_batiment = batiment.getChemins().get(id_source);
				}

			}catch(Exception e){
				Log.e("Error",e.toString());
				Toast.makeText(getApplicationContext(), "Le format du QrCode n'est pas celui attendu", Toast.LENGTH_SHORT).show();
			}
		}
		else{
			//invalid scan data or scan canceled
			Toast toast = Toast.makeText(getApplicationContext(), 
					"No scan data received!", Toast.LENGTH_SHORT);
			toast.show();
		}
	}
	@Override
	public void onLocationChanged(Location location) {
		HandleLocationChanged(location);

		//changement de la valeur du point de localisation courant


		this.ImHere.SetPosition((float)location.getLongitude(),
				(float)location.getLatitude());
		Log.v("localisation","imHere set to  : "+ImHere.getPosistion().getX()+
				" "+ImHere.getPosistion().getY());
		Log.v("localiser", localiser(new utils.Point(ImHere.getPosistion().getX(), ImHere.getPosistion().getY())).toString());
		if(this.location_enabled)
			refresh_location();
	}

	private void refresh_location() {
		if(!modeBatiment){
			Layer loc = _surfaceView.getRenderer().get_layers().get("localisation");
			Log.v("localisation","refresh_location : refresh requested");
			if(loc != null)
			{
				Log.v("localisation", " localisation.size : "+_surfaceView.getRenderer().get_layers().get("localisation").getFormes().size());
				loc.getParam().setEnable(this.location_enabled);
				loc.recreer();
				_surfaceView.changerCamera(ImHere.getPosistion().getX(), 
						ImHere.getPosistion().getY(),
						MyGLRenderer.z);
				_surfaceView.requestRender();
			}
		}
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub
		Log.d("Alex - locationLister", "provider disabled "+provider);

	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub
		Log.d("Alex - location listener", "provider enabled "+provider);
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
		Log.d("Alex locationlistener", "Status changed "+ provider + ", new status : "+status);
	}

	/*
	 * Function to get latitude
	 * 
	 */
	public double getLatitude(){
		if(location != null){
			latitude = location.getLatitude();
		}

		// return latitude
		return latitude;
	}

	/**
	 * Function to get longitude
	 * */
	public double getLongitude(){
		if(location != null){
			longitude = location.getLongitude();
		}

		// return longitude
		return longitude;
	}

	public void showSettingsAlert(){
		AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

		// Setting Dialog Title
		alertDialog.setTitle("GPS is settings");

		// Setting Dialog Message
		alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

		// Setting Icon to Dialog
		//alertDialog.setIcon(R.drawable.delete);

		// On pressing Settings button
		alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,int which) {
				Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
				startActivity(intent);
			}
		});

		// on pressing cancel button
		alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
			}
		});

		// Showing Alert Message
		alertDialog.show();
	}

	public void startUsingGPS()
	{
		if(locationManager != null){
			boolean isGPSEnabled = locationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER);

			boolean isNetworkEnabled = locationManager
					.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

			// Define a listener that responds to location updates
			if(!isNetworkEnabled && !isGPSEnabled){
				Log.d("no tracking", "no tracking");
				showSettingsAlert();
			}
			else{
				//				if (isNetworkEnabled) {
				//					locationManager.requestLocationUpdates(
				//							LocationManager.NETWORK_PROVIDER,
				//							5000,
				//							10, this);
				//					Log.d("Network", "Network");
				//
				//				}
				if(isGPSEnabled){
					// Register the listener with the Location Manager to receive location updates
					locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);
					Log.d("GPS", "GPS");
				}
				Log.d("locationManager ", "state = "+locationManager);

				//enable location Layer

				if(_surfaceView != null &&_surfaceView.getRenderer()!=null)
				{
					Layer loc = _surfaceView.getRenderer().get_layers().get("localisation");
					if(loc != null)
					{
						loc.getParam().setEnable(this.location_enabled);
						Log.v("localisation", " enableLocationTracker : location layer enabled");
					}
				}
			}
		}
	}
	public void stopUsingGPS(){
		if(locationManager != null){
			locationManager.removeUpdates(MainActivity.this);
		}      
	}

	public void demanderIP(){
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		alert.setTitle("Adresse IP du serveur");
		alert.setMessage("");

		// Set an EditText view to get user input 
		final EditText input = new EditText(this);

		SharedPreferences pref = getApplicationContext().getSharedPreferences(MainActivity.SESSION_VERSION, 0);
		input.setText(pref.getString("ADRESSE_SERVEUR", ""));

		alert.setView(input);

		alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String value = input.getText().toString();
				Net.ADRESSE_SERVEUR = value;

				SharedPreferences pref = getApplicationContext().getSharedPreferences(MainActivity.SESSION_VERSION, 0);
				Editor editor = pref.edit();
				editor.putString("ADRESSE_SERVEUR", value);
				editor.commit();

				new ChargerGraphesTask().execute();
			}
		});

		alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				// Canceled.
			}
		});

		alert.show();
	}

	/* --------------------------------------------------------------------------- */

	class ChargerGraphesTask extends AsyncTask<Void, Void, Void> {
		protected Void doInBackground(Void...donnees) {

			try{

				System.out.println("ChargerGrapheTask");

				SharedPreferences pref = getApplicationContext().getSharedPreferences(MainActivity.SESSION_VERSION, 0);
				Editor editor = pref.edit();

				String version = pref.getString(MainActivity.SESSION_KEY_VERSION,null);

				System.out.println("version :"+version);

				boolean recuperer = true;

				if(version == null)
					recuperer = true;
				else{			
					String versionServer = NetGraphe.getVersion();
					if(!version.equals(versionServer)){
						recuperer = true;
					}

				}

				String mapJSon = "";
				String batimentJSon = "";

				if(recuperer){
					version = NetGraphe.getVersion();
					editor.putString(MainActivity.SESSION_KEY_VERSION, version);
					editor.commit();

					mapJSon = NetGraphe.getGrapheJSon(false);
					batimentJSon = NetGraphe.getGrapheJSon(true);

					LecteurFichier.WriteFileOnSDCard("map.json", mapJSon);
					LecteurFichier.WriteFileOnSDCard("batiment.json", batimentJSon);

				}else{
					mapJSon = LecteurFichier.readFileFromSDCard("map.json");
					batimentJSon = LecteurFichier.readFileFromSDCard("batiment.json");
				}

				System.out.println("mapJSon:\n"+mapJSon);

				ObjectMapper mapper = new ObjectMapper();
				try {
					Graphe map = mapper.readValue(mapJSon, Graphe.class);
					if(map != null)
						MainActivity.this.graphe = map;
				} catch (Exception e) {
					e.printStackTrace();
				}

				mapper = new ObjectMapper();
				try {
					Graphe batiment = mapper.readValue(batimentJSon, Graphe.class);
					if(batiment != null)
						MainActivity.this.graphe = batiment;
				} catch (Exception e) {
					e.printStackTrace();
				}

				runOnUiThread(new Runnable(){

					@Override
					public void run() {
						chargerDonnees();
					}

				});

			}catch(Exception e){
				e.printStackTrace();
			}
			return null;
		}

		protected void onPostExecute(){
		}
	}

	/* --------------------------------------------------------------------------- */

	class DemanderCheminTask extends AsyncTask<String, Void, Void> {
		protected Void doInBackground(String...donnees) {

			try{

				String idSource = donnees[0];
				String idDestination = donnees[1];

				String cheminJSon = NetGraphe.getCheminJSon(modeBatiment, idSource, idDestination);
				List<INoeud> chemin = new ArrayList<INoeud>();
				ObjectMapper mapper = new ObjectMapper();
				try {
					chemin = mapper.readValue(cheminJSon, chemin.getClass());
				} catch (Exception e) {
					e.printStackTrace();
				}

				final List<INoeud> chemins = chemin;

				runOnUiThread(new Runnable(){

					@Override
					public void run() {
						if(_surfaceView  != null){
							_surfaceView.getRenderer().ajouterChemin(afficherChemin(chemins));                    
							_surfaceView.requestRender();
						}
					}

				});

			}catch(Exception e){}
			return null;
		}

		protected void onPostExecute(){
		}
	}


}
